#include "pch.h"
#include "TetrisShape.h"

BOOLEAN TetrisShape::IsFull()
{
	if (m_current->Top == 0)
	{
		int srow = m_current->Height;
		int scol = m_current->Width;

		for (int row = 0; row < srow; row++)
		{
			for (int col = 0; col < scol; col++)
			{
				CELLCUBE cube = m_current->GetCube(row, col);
				CELLCUBE cubeBase = GetCube(m_current->Top + row, m_current->Left + col);

				if (cube.isShow && cubeBase.isShow)
					return true;
			}
		}
	}
	return false;
}

void TetrisShape::MoveDown()
{

	if (!IsBottom())
	{
		m_current->Top++;
	}
	else
	{
		m_preview = m_current;
		m_current = m_next;

		RemoveRows();
		RandomShape();
	}
}

BOOLEAN TetrisShape::IsBlock()
{
	int srow = m_current->Height;
	int scol = m_current->Width;

	for (int row = 0; row < srow; row++)
	{
		for (int col = 0; col < scol; col++)
		{
			CELLCUBE cubeFloat = m_current->GetCube(row, col);
			CELLCUBE cubeBaseL = GetCube(m_current->Top + row, m_current->Left + col - 1);
			CELLCUBE cubeBaseR = GetCube(m_current->Top + row, m_current->Left + col + 1);
			if (m_current->Left > 0 && cubeFloat.isShow && cubeBaseL.isShow)
				return true;
			if ((m_current->Left + scol < 10 && cubeFloat.isShow && cubeBaseR.isShow))
				return true;
		}
	}
	return false;
}

void TetrisShape::MoveLeft()
{
	if (m_current->Left > 0 && !IsBlock())
	{
		m_current->Left--;
	}
}

void TetrisShape::MoveRight()
{
	if (m_current->Left + m_current->Width < 10 && !IsBlock())
	{
		m_current->Left++;
	}
}

void TetrisShape::Drop()
{
	int srow = m_current->Height;
	int scol = m_current->Width;

	int slen = scol;
	int ntop = 20 - srow;
	int curtop = m_current->Top;
	for (int _top = curtop; _top < ntop; _top++)
	{
		for (int row = 0; row < srow; row++) {
			for (int col = 0; col < scol; col++)
			{
				CELLCUBE cubeBaseD = GetCube(_top + row + 1, m_current->Left + col);

				if (cubeBaseD.isShow)
				{
					m_current->Top = _top;
					MoveDown();
					return;
				}
			}
		}
	}
	m_current->Top = ntop;
	MoveDown();
}

void TetrisShape::ChangeDirection()
{
	m_current->ChangeDirection();
}

void TetrisShape::Reset()
{
	for (int i = 0; i < 200; i++) {
		m_data[i].isShow = 0;
	}
}

void TetrisShape::RemoveRows()
{
	if (m_preview)
	{
		for (int row = 0; row < m_preview->Height; row++)
		{
			for (int col = 0; col < m_preview->Width; col++)
			{
				CELLCUBE cube = m_preview->GetCube(row, col);
				if (cube.isShow)
				{
					SetCube(m_preview->Top + row, m_preview->Left + col, m_preview->Color, cube.isShow, cube.type);
				}
			}
		}
		delete m_preview;
	}

	int removeCount = 0;
	for (int row = 0; row < 20; row++)
	{
		bool full = true;
		for (int col = 0; col < 10; col++)
		{
			CELLCUBE cube = GetCube(row, col);
			full = full && cube.isShow;
		}
		if (full)
		{

			removeCount++;
			for (int ui = row - 1; ui > 0; ui--)
			{
				for (int uj = 0; uj < 10; uj++)
				{
					CELLCUBE pre = GetCube(ui, uj);
					SetCube(ui + 1, uj, pre.color, pre.isShow, pre.type);
				}
			}
		}
	}

}

void TetrisShape::MoveQuickly()
{
	if (!IsBottom())
	{
		m_current->Top++;
	}
}


bool TetrisShape::IsBottom()
{
	int srow = m_current->Height;
	int scol = m_current->Width;

	if (m_current->Top + srow < 20)
	{
		for (int row = 0; row < srow; row++)
		{
			for (int col = 0; col < scol; col++)
			{
				CELLCUBE cubeFloat = m_current->GetCube(row, col);

				if (cubeFloat.isShow) {
					CELLCUBE cubeBaseD = GetCube(m_current->Top + row + 1, m_current->Left + col);
					if (cubeBaseD.isShow)
						return true;
				}
			}
		}
	}
	return m_current->Top + srow == 20;
}

void TetrisShape::RandomShape()
{
	ShapeStruct* shape = RandomNext();

	if (m_current == NULL)
	{
		m_current = shape;
		ShapeStruct* shape1 = RandomNext();
		m_next = shape1;
	}
	else
	{
		m_next = shape;
	}
	srand((unsigned)time(NULL));
	int index = rand() % 3;
	for (int r = 0; r < index; r++)
	{
		m_next->ChangeDirection();
	}
}

ShapeStruct* TetrisShape::RandomNext()
{
	srand((unsigned)time(NULL));
	int index = rand() % 7;

	ShapeStruct* shape = new ShapeStruct();
	shape->Shape = index + 1;
	BLOCK baseBlock = BaseShapes[index];
	//BLOCK display;
	//memcpy(&display, baseBlock, sizeof(baseBlock));
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			shape->SetCube(i, j, baseBlock.color, baseBlock.data[i * 4 + j]);
		}
	}
	shape->Width = baseBlock.col;
	shape->Height = baseBlock.row;
	shape->Color = baseBlock.color;
	return shape;
}

TetrisShape::TetrisShape()
{
}
